#define POWERPIN  4             // LED  #1
#define SIGNALPIN  3             // LED #2
#define TUNEPIN1 5
#define TUNEPIN2 4
#define TUNEPIN3 3
#define TUNEPIN4 2

// PINs for DAC
#define DATAOUT 11//MOSI
#define DATAIN 12//MISO - not used, but part of builtin SPI
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss


#define BASE_TONE_LEN  25 // msec
#define ON_TIME 60      // Percent

int val1;
int val2;
int val3;
int val4;

#define SIG_CNT 20
int sig_cnt = 0 ;

/**********
unsigned int NOTE1[] = {0x3C08,0x3E08,0x4008,0x3C08,0x3C08,0x3E08,0x4008,0x3C08,
                        0x4008,0x4108,0x4310,0x4008,0x4108,0x4210,
                        0x4304,0x4504,0x4304,0x4104,0x4008,0x3C08,0x4304,0x04504,0x4304,0x4104,0x4008,0x3C08,
                        0x3C08,0x3708,0x3C10,0x3C08,0x3708,0x3C10};


unsigned int NOTE2[] = {0x0040,
                        0x3C08,0x3E08,0x4008,0x3C08,0x3C08,0x3E08,0x4008,0x3C08,
                        0x4008,0x4108,0x4310,0x4008,0x4108,0x4210,
                        0x4304,0x4504,0x4304,0x4104,0x4008,0x3C08,0x4304,0x04504,0x4304,0x4104,0x4008,0x3C08,
                        0x3C08,0x3708,0x3C10,0x3C08,0x3708,0x3C10};
********************/

unsigned int NOTE1[] = {0x3C04, 0x3C04, 0x3C04, 0x3C04, 0x0004, 0x0004, 0x0004, 0x0004, 0x3C04, 0x3C04, 0x0004, 
                        0x0004, 0x3C04, 0x3C04, 0x0004, 0x0004, 0x3C04, 0x3C04, 0x4804, 0x4804, 0x0004, 0x0004, 
                        0x0004, 0x0004, 0x3C04, 0x3C04, 0x3004, 0x3004, 0x0004, 0x0004, 0x0004, 0x0004, 0x3C04, 
                        0x4804, 0x5404, 0x4804, 0x3C04, 0x4804, 0x5404, 0x4804, 0x3C04, 0x4804, 0x5404, 0x4804, 
                        0x3C04, 0x4804, 0x5404, 0x4804, 0x3C08, 0x3C08 };

// NOTE2
unsigned int NOTE2[] = {0x0004, 0x0004, 0x0004, 0x0004, 0x3C04, 0x3C04, 0x3C04, 0x3C04, 0x0004, 0x0004, 0x3C04, 
                        0x3C04, 0x0004, 0x0004, 0x3C04, 0x3C04, 0x0004, 0x0004, 0x0004, 0x0004, 0x3C04, 0x3C04, 
                        0x4804, 0x4804, 0x0004, 0x0004, 0x0004, 0x0004, 0x3C04, 0x3C04, 0x3004, 0x3004, 0x0004, 
                        0x0004, 0x3C04, 0x4804, 0x5404, 0x4804, 0x3C04, 0x4804, 0x0004, 0x0004, 0x3C04, 0x4804, 
                        0x5404, 0x4804, 0x3C04, 0x4804, 0x3C08, 0x3C08};



#define MAX_N1_CNT 50
#define MAX_N2_CNT 50

//Note No. Hex
// C1  24  18
// C2  36  24
// C3  48  30
// C4  60  3C
// C5  72  48
// C6  84  54
// C7  96  60
// C8 108  6C
// C9 120  78
// 001 0x01   B00001 note len 1/32 
// 002 0x02   B00010 note len 1/16
// 004 0x04   B00100 note len 1/8
// 008 0x08   B01000 note len 1/4
// 016 0x10   B10000 note len 1/2


int n1_cnt = 0;
int n2_cnt = 0;

int n1_th;
int n2_th;

int n1_pt = -1 ;
int n2_pt = -1;


void setup() {

  // initialize DAC
  byte clr;
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device

  /* ======== FOR DAC */
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  /* ==================== */
  delay(10);

  pinMode(POWERPIN, OUTPUT);
  pinMode(SIGNALPIN, OUTPUT);

  digitalWrite(POWERPIN, HIGH);
  for (int i = 0 ; i < 3 ; i++){
    digitalWrite(SIGNALPIN, HIGH);
    delay(150);
    digitalWrite(SIGNALPIN, LOW);
    delay(150);
  } 
  NOTE_OFF(1);
  NOTE_OFF(2);
  delay(200);

}


void loop () {
  int n1_tone;
  int n1_len;
  int n2_tone;
  int n2_len;

  val1 = analogRead(TUNEPIN1) ;
  val2 = analogRead(TUNEPIN2) ;
  val3 = analogRead(TUNEPIN3) ;
  val4 = analogRead(TUNEPIN4) ;

  if (sig_cnt > 0 ) {
    sig_cnt--;
  }

  n1_cnt--;
  n2_cnt--;
  
  if ( n1_cnt <= 0 ) {  // goto next note.
    n1_pt++ ;
    if (n1_pt >= MAX_N1_CNT ) {
      n1_pt = 0 ;   // start from top.
    }
    n1_len  = NOTE1[n1_pt] & 0x00FF ;
    n1_cnt = n1_len * BASE_TONE_LEN ;
    n1_th  = n1_cnt - (n1_cnt * ON_TIME / 100);

    n1_tone = (NOTE1[n1_pt] >> 8 ) & 0x00FF ;
    NOTE_ON (1,n1_tone);  // ###############
  }
  
  if ( n2_cnt <= 0 ) {  // goto next note.
    n2_pt++ ;
    if (n2_pt >= MAX_N2_CNT ) {
      n2_pt = 0 ;   // start from top.
    }
    n2_len  = NOTE2[n2_pt] & 0x00FF ;
    n2_cnt = n2_len * BASE_TONE_LEN ;
    n2_th  = n2_cnt - (n2_cnt * ON_TIME / 100);

    n2_tone = (NOTE2[n2_pt] >> 8 )& 0x00FF ;

    NOTE_ON(2, n2_tone);  // ###############
  }
  
  if ( n1_cnt == n1_th ) {
     NOTE_OFF(1);
  }
  
  
  if ( n2_cnt == n2_th ) {
     NOTE_OFF(2);
  }
  /*
  Serial.print("n1_cnt:");
  Serial.println(n1_cnt);
  Serial.print("n2_cnt:");
  Serial.println(n2_cnt);
  */
  
  if (sig_cnt <= 0 ) {
    digitalWrite(SIGNALPIN,LOW);
  }
  
  delay(1);
}

void NOTE_ON (int machine, int tone )
{
  //
  if ( tone == 0 ) {
    NOTE_OFF(machine);
  } else {
    /*
    Serial.print("NOTE ON:");
    Serial.print(machine);
    Serial.print("/");
    Serial.println(tone);
    */

    digitalWrite(SIGNALPIN,HIGH);
    sig_cnt = SIG_CNT;
    
    playNote(machine, tone);
  }
}
void NOTE_OFF (int machine)
{
  //  
  /*
  Serial.print("NOTE OFF:");
  Serial.println(machine);
  */
  
  digitalWrite(SIGNALPIN, LOW);
  write_value(machine,0);

}

void playNote(int machine, int incomingByte)
{
  int data;
  int base_v;
  int diff_v;

  float v2;
  int base = 3000;
  int TUNE_RANGE= 512;

  if (machine == 1 ){
     base_v=val1;
     diff_v=val2;
  } else {
     base_v=val3;
     diff_v=val4;
  }

  /* when TUNE_RANGE = 512  
    base_v = 0  -->  base = base - 256
    base_v = 512  -->  base = base  - 256 + 512 /2 = base
    base_v = 1023  -->  base = base - 256 + 1023/2 = base + 255
  */
  base = base -  (TUNE_RANGE /2  -  base_v / (TUNE_RANGE/1024) );


  // old code
  // base = base - ( base_v / 4 - 128);

  // v2 differs from  24-10 to 24+10  (because diff_v differs from 0 to 1023 
  v2 =  24+20*(diff_v-512)/1024;
  data = (v2*(incomingByte-60)+base);
  write_value (machine, data);

  // 1270 C4 60
  // 1125 C3 48
  // 980  C2 36    
  // 835  C1 24 
  // 690  C0 12      
}


// Serial interface data structure
// ================================
// bit 15 A/B: DACA or DACB Select bit
//    1 = Write to DACB
//    0 = Write to DACA
// bit 14 BUF: VREF Input Buffer Control bit
//    1 = Buffered
//    0 = Unbuffered
// bit 13 GA: Output Gain Select bit
//    1 = 1x (VOUT = VREF * D/4096)
//    0 = 2x (VOUT = 2 * VREF * D/4096)
// bit 12 SHDN: Output Power Down Control bit
//    1 = Output Power Down Control bit
//    0 = Output buffer disabled, Output is high impedance
// bit 11-0 D11:D0: DAC Data bits
//    12 bit number “D” which sets the output value. Contains a value between 0 and 4095.
//
void write_value(int machine, uint16_t sample)
{
  // return; // FOR DEBUG USE ONLY
  uint8_t dacSPI0 = 0;
  uint8_t dacSPI1 = 0;
  dacSPI0 = (sample >> 8) & 0x00FF;
  dacSPI0 |= 0x10;
  if ( machine == 2) {
     dacSPI0 |= 0x80;
  }
  dacSPI1 = sample & 0x00FF;
  digitalWrite(SLAVESELECT,LOW);
  SPDR = dacSPI0;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };

  SPDR = dacSPI1;
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };  
  digitalWrite(SLAVESELECT,HIGH);
  // delay(5);
}






